/*
 * Copyright 2008-2023 dexian.vip. All rights reserved.
 * Support: http://www.dexian.vip
 * License: http://www.dexian.vip/license
 */

package vip.dexian.admin.controller;

import vip.dexian.admin.base.BaseController;
import vip.dexian.admin.command.AdminRoleUpdateCommand;
import vip.dexian.admin.command.AdminSaveCommand;
import vip.dexian.admin.command.AdminUpdateCommand;
import vip.dexian.admin.dto.AdminDTO;
import vip.dexian.admin.dto.AdminPrincipal;
import vip.dexian.admin.dto.AdminRoleDTO;
import vip.dexian.admin.enums.DataScopeEnum;
import vip.dexian.admin.enums.GenderEnum;
import vip.dexian.admin.enums.OperateTypeEnum;
import vip.dexian.admin.log.AdminLog;
import vip.dexian.admin.searcher.AdminPageSearcher;
import vip.dexian.admin.service.AdminService;
import vip.dexian.admin.service.DepartmentService;
import vip.dexian.admin.service.OnlineAdminService;
import vip.dexian.admin.service.RoleDepartmentService;
import vip.dexian.admin.service.RoleService;
import vip.dexian.common.Message;
import vip.dexian.common.query.Page;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

/**
 * 管理员管理
 *
 * @author 挺好的 2023年06月05日 08:45:00
 */
@Controller ("adminAdminController")
@RequestMapping ("/admin/admin")
public class AdminController extends BaseController {

    /**
     * 管理员Service
     */
    @Resource (name = "adminServiceImpl")
    private AdminService adminService;

    /**
     * 部门
     */
    @Resource (name = "departmentServiceImpl")
    private DepartmentService departmentService;

    /**
     * 角色
     */
    @Resource (name = "roleServiceImpl")
    private RoleService roleService;

    /**
     * 在线管理
     */
    @Resource (name = "onlineAdminServiceImpl")
    private OnlineAdminService onlineAdminService;

    /**
     * 角色关联的部门
     */
    @Resource (name = "roleDepartmentServiceImpl")
    private RoleDepartmentService roleDepartmentService;

    /**
     * 管理员列表页面
     *
     * @param searcher
     *         管理员查询器
     * @param model
     *         {@link org.springframework.ui.ModelMap}
     *
     * @return list view
     */
    @GetMapping ("/list")
    @AdminLog (module = "admin", description = "查看管理员列表", type = OperateTypeEnum.LIST)
    public String page (AdminPageSearcher searcher, ModelMap model) {
        // 将searcher添加到model中
        searcher.addAttribute(model);

        Page <AdminDTO> page = this.adminService.findPage(searcher.query());

        AdminPrincipal adminPrincipal = this.adminService.getCurrent();

        // 如果是自定义的
        if (DataScopeEnum.CUSTOM.equals(adminPrincipal.getDataScope())) {
            List <Long> roleIds = adminPrincipal.getRoles().stream().map(AdminRoleDTO::getRoleId).sorted().toList();
            List <Long> departmentIds = this.roleDepartmentService.findDepartmentIds(roleIds);
            model.addAttribute("departmentIds", departmentIds);

            // 如果是本级的，就增加本级的操作
        } else if (DataScopeEnum.SAME_LEVEL.equals(adminPrincipal.getDataScope())) {
            List <Long> departmentIds = new ArrayList <>();
            departmentIds.add(adminPrincipal.getDepartmentId());
            model.addAttribute("departmentIds", departmentIds);
        }

        model.addAttribute("page", page);
        model.addAttribute("departments", this.departmentService.findTree());

        return "/admin/admin/admin/list";
    }

    /**
     * 进入管理员保存页面
     *
     * @return save view
     */
    @GetMapping ("/save")
    public String add (ModelMap model) {
        model.addAttribute("departments", this.departmentService.findTree());
        model.addAttribute("roles", this.roleService.findAll());
        model.addAttribute("gender", GenderEnum.values());
        return "/admin/admin/admin/save";
    }

    /**
     * 保存管理员
     *
     * @param command
     *         管理员保存command
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/save")
    @ResponseBody
    @AdminLog (module = "admin", description = "保存管理员", type = OperateTypeEnum.SAVE)
    public Message save (AdminSaveCommand command) {

        this.adminService.save(command);

        return Message.success();
    }

    /**
     * 进入编辑页面
     *
     * @param model
     *         {@link org.springframework.ui.ModelMap}
     * @param id
     *         管理员id
     *
     * @return update view
     */
    @GetMapping ("/update")
    public String update (Long id, ModelMap model) {
        AdminDTO adminDTO = this.adminService.find(id);
        model.addAttribute("content", adminDTO);
        model.addAttribute("departments", this.departmentService.findTree());
        model.addAttribute("roles", this.roleService.findAll());
        model.addAttribute("gender", GenderEnum.values());
        return "/admin/admin/admin/update";
    }

    /**
     * 更新管理员
     *
     * @param command
     *         管理员更新command
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/update")
    @ResponseBody
    @AdminLog (module = "admin", description = "更新管理员", type = OperateTypeEnum.UPDATE)
    public Message update (AdminUpdateCommand command) {
        this.adminService.update(command);
        return Message.success();
    }

    /**
     * 删除管理员
     *
     * @param ids
     *         id列表，客户端传递的参数为： ids=1&ids=2&ids=3
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/delete")
    @ResponseBody
    @AdminLog (module = "admin", description = "删除管理员", type = OperateTypeEnum.DELETE)
    public Message delete (Long[] ids) {
        this.adminService.delete(ids);
        return Message.success();
    }

    /**
     * 启用或者禁用 管理员
     *
     * @param id
     *         管理员id
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/enable_or_disable")
    @ResponseBody
    @AdminLog (module = "admin", description = "启用禁用", type = OperateTypeEnum.UPDATE)
    public Message enableOrDisabled (Long id) {
        this.adminService.enabledOrDisabled(id);
        return Message.success();
    }

    /**
     * 锁定解锁管理员
     *
     * @param id
     *         管理员id
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/lock_or_unlock")
    @ResponseBody
    @AdminLog (module = "admin", description = "锁定解锁", type = OperateTypeEnum.UPDATE)
    public Message lockOrUnlock (Long id) {
        this.adminService.lockOrUnlock(id);
        return Message.success();
    }


    /**
     * 修改密码
     *
     * @param id
     *         管理员id
     * @param password
     *         新密码
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/modify_password")
    @ResponseBody
    @AdminLog (module = "admin", description = "修改密码", type = OperateTypeEnum.UPDATE)
    public Message modifyPassword (Long id, String password) {
        this.adminService.modifyPassword(id, password);
        return Message.success();
    }

    /**
     * 修改手机号码
     *
     * @param id
     *         管理员id
     * @param mobile
     *         新手机号码
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/modify_mobile")
    @ResponseBody
    @AdminLog (module = "admin", description = "修改手机号码", type = OperateTypeEnum.UPDATE)
    public Message modifyMobile (Long id, String mobile) {
        this.adminService.modifyMobile(id, mobile);
        return Message.success();
    }

    /**
     * 强制退出指定登录用户
     *
     * @param id
     *         管理员id
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/force_logout")
    @ResponseBody
    public Message forceLogout (Long id) {
        this.onlineAdminService.logoutById(id);
        return Message.success();
    }

    /**
     * 修改角色
     *
     * @param id
     *         管理员id
     *
     * @return role view
     */
    @GetMapping ("/modify_role")
    public String modifyRole (Long id, ModelMap model) {

        model.addAttribute("content", this.adminService.find(id));
        model.addAttribute("roles", this.roleService.findAll());

        return "/admin/admin/admin/role";

    }

    /**
     * 修改角色
     *
     * @param command
     *         修改角色指令
     *
     * @return {@link vip.dexian.common.Message}
     */
    @PostMapping ("/modify_role")
    @ResponseBody
    @AdminLog (module = "admin", description = "修改角色", type = OperateTypeEnum.UPDATE)
    public Message modifyRole (AdminRoleUpdateCommand command) {
        this.adminService.modifyRole(command);
        return Message.success();
    }


    /**
     * 校验唯一用户名是否存在
     *
     * @param username
     *         用户名
     * @param oldUsername
     *         原用户名
     *
     * @return 用户名是否存在
     */
    @GetMapping ("/check_username")
    @ResponseBody
    public boolean checkUsername (String username, String oldUsername) {

        if (StringUtils.equals(username, oldUsername)) {
            return true;
        }

        return !this.adminService.isUsernameExists(username);
    }

    /**
     * 校验唯一手机号码是否存在
     *
     * @param mobile
     *         手机号码
     * @param oldMobile
     *         原手机号码
     *
     * @return 手机号码是否存在
     */
    @GetMapping ("/check_mobile")
    @ResponseBody
    public boolean checkMobile (String mobile, String oldMobile) {

        if (StringUtils.equals(mobile, oldMobile)) {
            return true;
        }

        return !this.adminService.isMobileExists(mobile);
    }

}
